//
//  JZLPhotoBrowser.m
//  JZLPhotoBrowser
//
//  Created by jackylong on 2017/6/5.
//  Copyright © 2017年 jackylong. All rights reserved.
//

#import "JZLPhotoBrowser.h"
#import "JZLPhoto.h"
//#import "UIImageView+WebCache.h"
#import "JZLProgressView.h"
#import <AssetsLibrary/AssetsLibrary.h>
#import <CoreLocation/CoreLocation.h>
#import <AVFoundation/AVFoundation.h>
#import <Photos/PHPhotoLibrary.h>
#import <Photos/Photos.h>
#import <UIImageView+WebCache.h>
#import <Toast.h>
#import "generalToolBox.h"

typedef NS_ENUM(NSUInteger, kLoadImageType ){
    kLoadImageTypeKnown = 0,
    kLoadImageTypeFromURL = 1,
    kLoadImageTypeFromImage = 2
};


@interface JZLPhotoBrowser ()<UIScrollViewDelegate>
/** 是否取消点击事件 默认：NO */
@property (nonatomic, assign) BOOL isCancelTap;
/** 存放JZLPhoto */
@property (nonatomic, strong) NSMutableArray *photos;
/** 存放图片url */
@property (nonatomic, strong) NSArray *urlArr;
/** 点击的下标 */
@property (nonatomic, assign) NSInteger index;
/** 索引显示 */
@property (nonatomic, strong) UILabel *indexLbl;
/** 每张图片的父视图(小的scrollview) */
@property (nonatomic, strong) NSMutableArray *smallScViewArray;

/** 黑色背景 */
@property (nonatomic, strong) UIView *blackView;
/** 滑动的scrollview */
@property (nonatomic, strong) UIScrollView *bgScrollView;

@property (nonatomic, strong) UIView *backView;

@property (nonatomic, assign) int height;

/** 保存按钮 */
@property (nonatomic, strong) UIButton *saveBtn;

@property (nonatomic, assign) CGRect myFrame;

@property (nonatomic, copy) NSArray *imageArray ;

@property (nonatomic, assign) kLoadImageType loadImageType ;

@end


@implementation JZLPhotoBrowser
    
+ (instancetype)photoBrowser {
    return [[self alloc] init];
}

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.myFrame = frame;
    }
    return self;
}

/// 如果是传UIImage对象数组 就调用这个
/// @param imageArr 图片数组
/// @param index 当前的下标
/// @param superview 在父视图上显示
+ (instancetype)showPhotoBrowserWithImageArr:(NSArray<UIImage *> *)imageArr
                                     atIndex:(NSInteger)index
                                      onView:(UIView *)superview
                                canTapCancel:(BOOL)cantapcancel{
    if (superview == nil) {
        superview = [UIApplication sharedApplication].keyWindow;
    }
    JZLPhotoBrowser *photoBrowser = [[JZLPhotoBrowser alloc] initWithFrame:superview.bounds];
    photoBrowser.loadImageType = kLoadImageTypeFromImage;
    photoBrowser.isCancelTap = cantapcancel;
    
    if(index > imageArr.count-1){
        if(imageArr.count>0 ){
            index = imageArr.count-1;
        }
    }
    if(index < 0){
        index = 0;
    }
    photoBrowser.index = index;
    photoBrowser.backView = superview;
    if(imageArr){
        photoBrowser.imageArray = [imageArr mutableCopy];
    }
    [photoBrowser setupUI];
    [photoBrowser show];
    return photoBrowser;
}

/// 如果是传网络图数组 就调用这个
/// @param urlArr 网络图片url数组
/// @param index 当前下标
/// @param superview 父视图
+ (instancetype)showPhotoBrowserWithURLArr:(NSArray<NSString *> *)urlArr
                                   atIndex:(NSInteger)index
                                    onView:(UIView *)superview
                              canTapCancel:(BOOL)cantapcancel{
    if (superview == nil) {
        superview = [UIApplication sharedApplication].keyWindow;
    }
    JZLPhotoBrowser *photoBrowser = [[JZLPhotoBrowser alloc] initWithFrame:superview.bounds];
    photoBrowser.loadImageType = kLoadImageTypeFromURL;
    photoBrowser.isCancelTap = cantapcancel;
    
    if(index > urlArr.count-1){
        if(urlArr.count>0 ){
            index = urlArr.count-1;
        }
    }
    if(index < 0){
        index = 0;
    }
    photoBrowser.index = index;
    photoBrowser.backView = superview;
    if(urlArr){
        photoBrowser.urlArr = [urlArr mutableCopy];
    }
    [photoBrowser setupUI];
    [photoBrowser show];
    return photoBrowser;
}
    
/** 创建布局 */
- (void)setupUI {
    [self addSubview:self.blackView];
    [self addSubview:self.bgScrollView];
    self.frame = self.myFrame;
    [_backView addSubview:self];
    [self addSubview:self.saveBtn];
    [self bringSubviewToFront:self.saveBtn];
    [self addSubview:self.indexLbl];
    [self bringSubviewToFront:self.indexLbl];
}

/** 展示图片浏览器 */
- (void)show {
    if (self.loadImageType == kLoadImageTypeFromURL) {
        self.bgScrollView.contentSize = CGSizeMake(self.myFrame.size.width * self.urlArr.count, 0);
        [self creatSmallScrollView];
    }else if (self.loadImageType == kLoadImageTypeFromImage){
        self.bgScrollView.contentSize = CGSizeMake(self.myFrame.size.width * self.imageArray.count, 0);
        [self createImageScroll];
    }
    self.bgScrollView.contentOffset = CGPointMake(self.myFrame.size.width * self.index, 0);
}

// 退出图片浏览器 释放self 必须调用 否则会内存泄漏
- (void)cancel {
    [[SDImageCache sharedImageCache] clearMemory];
    [[SDWebImageManager sharedManager] cancelAll];
    [self removeFromSuperview];
}

#pragma mark ---- 加载UIImage图片 ---- start
- (void)createImageScroll{
    [self.photos removeAllObjects];
    //1.创建子scrollview
    for(int index = 0 ; index < self.imageArray.count ; index++){
        UIScrollView *scrollView = [[UIScrollView alloc] init];
        scrollView.frame = CGRectMake(self.myFrame.size.width * index, 0, self.myFrame.size.width, self.myFrame.size.height);
        scrollView.backgroundColor = [UIColor clearColor];
        scrollView.delegate = self;
        scrollView.tag = index;
        scrollView.maximumZoomScale=3.0;
        scrollView.minimumZoomScale=1;
        JZLPhoto *photo = [self addGestureToImageView];
        photo.image = [self.imageArray objectAtIndex:index];
        [self.photos addObject:photo];
        [scrollView addSubview:photo];
        [self.smallScViewArray addObject:scrollView];
        [self.bgScrollView addSubview:scrollView];
        [self setPhotoFrame:photo];
    }
}

#pragma mark ---- 加载网络图片 ---- start
/// 加载url图片
/// @param imageView 要加载图片的视图
/// @param url 网络图片url
/// @param complete 加载完之后的回调
- (void)loadImage:(UIImageView*)imageView
          withURL:(NSURL*)url
     withComplete:(void(^ _Nullable)(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL))complete{
    [imageView sd_setImageWithURL:url completed:complete];
}

/// 创建子scrollview
/// @param url 根据url加载图片 然后放到scrollview上
/// @param index 要把子scrollview加载到对应的位置
- (void)createImageScrollViewWithURL:(NSURL*)url atIndex:(NSUInteger)index{
    UIScrollView *scrollView = [[UIScrollView alloc] init];
    scrollView.frame = CGRectMake(self.myFrame.size.width * index, 0, self.myFrame.size.width, self.myFrame.size.height);
    scrollView.backgroundColor = [UIColor clearColor];
    scrollView.delegate = self;
    scrollView.tag = index;
    scrollView.maximumZoomScale=3.0;
    scrollView.minimumZoomScale=1;
    JZLPhoto *photo = [self addGestureToImageView];
    if (index < self.photos.count && photo) {
        [self.photos replaceObjectAtIndex:index withObject:photo];
        [scrollView addSubview:photo];
        [self.smallScViewArray addObject:scrollView];
        [self.bgScrollView addSubview:scrollView];
        [self loadImage:photo withURL:url withComplete:^(UIImage *image, NSError *error, SDImageCacheType cacheType, NSURL *imageURL) {
            if (image != nil) {
                //缓存过的图片
                photo.image = image;
                [self setPhotoFrame:photo];
            }else {
                //下载失败,显示占位图
                photo.bounds = CGRectMake(0, 0, self.myFrame.size.width, 240);
                photo.center = CGPointMake(self.myFrame.size.width/2, self.myFrame.size.height/2-self.height);
                CGFloat photoY = ((self.myFrame.size.height-self.height) - photo.frame.size.height)/2;
                CGRect photoF = photo.frame;
                if (photoY>0) {
                    photoF.origin.y = photoY;
                } else {
                    photoF.origin.y = 0;
                }
                photo.frame = photoF;
                photo.contentMode = UIViewContentModeScaleAspectFit;
                photo.image = [UIImage imageNamed:@"placeholder.jpg"];
            }
        }];
    }
}

/// 创建视图，一次加载3个图片 不是一次性加载
- (void)creatSmallScrollView {
    NSUInteger cnt = self.urlArr.count;
    if(cnt>0){
        if(cnt<=3){
            for (int i = 0; i < cnt; i++) {
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i]] atIndex:i];
            }
        }else{
            if(self.index==0){
                for (int i = 0; i < 3; i++) {
                    [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i]] atIndex:i];
                }
            }else if (self.index == (cnt-1)){
                NSUInteger i = self.index;
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i]] atIndex:i];
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i-1]] atIndex:i-1];
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i-2]] atIndex:i-2];
            }else{
                NSUInteger i = self.index;
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i+1]] atIndex:i+1];
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i-1]] atIndex:i-1];
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[i]] atIndex:i];
            }
        }
    }
}

/** 设置imageView的frame */
- (void)setPhotoFrame:(JZLPhoto *)photo {
    UIScrollView *smallScrollView = (UIScrollView *)photo.superview;
    self.blackView.alpha = 1.0;
    CGFloat ratio = (double)photo.image.size.height / (double)photo.image.size.width;
    CGFloat photoWidth = self.myFrame.size.width;
    CGFloat photoHeight = ratio*photoWidth;
    
    if (photoHeight < self.myFrame.size.height) {
        photo.center = CGPointMake(self.myFrame.size.width / 2, self.myFrame.size.height / 2 -self.height);
        photo.bounds = CGRectMake(0, 0, photoWidth, photoHeight);
        CGFloat photoY = ((self.myFrame.size.height-self.height) - photo.frame.size.height)/2;
        CGRect photoF = photo.frame;
        if (photoY>0) {
            photoF.origin.y = photoY;
        }else{
            photoF.origin.y = 0;
        }
        photo.frame = photoF;
    }else {//长图的处理
        if (photoHeight == self.myFrame.size.width) {
            CGFloat height;
            if (isiPhoneX) {
                height = 84;
            }else{
                height = 64;
            }
            photo.frame = CGRectMake(0, -height, photoWidth, photoHeight);
            smallScrollView.contentSize = CGSizeMake(self.myFrame.size.width, photoHeight);
            
        }else{
            photo.frame = CGRectMake(0, 0, photoWidth, photoHeight);
            smallScrollView.contentSize = CGSizeMake(self.myFrame.size.width, photoHeight);
        }
    }
}

/// 给图片添加缩放和双击手势
- (JZLPhoto *)addGestureToImageView {
    JZLPhoto *photo = [[JZLPhoto alloc] init];
    photo.userInteractionEnabled = YES;
    photo.contentMode = UIViewContentModeScaleToFill;
    UITapGestureRecognizer *zoomTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(zoomTap:)];
    zoomTap.numberOfTapsRequired = 2;
    [photo addGestureRecognizer:zoomTap];
    if (self.isCancelTap) {
        UITapGestureRecognizer *photoTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(photoTap:)];
        [photo addGestureRecognizer:photoTap];
        //如果zonmTap识别出双击事件,那么photoTap不会被执行
        [photoTap requireGestureRecognizerToFail:zoomTap];
    }
    //默认给一个位置,不然展开动画很难看
    photo.center = CGPointMake(self.myFrame.size.width / 2, self.myFrame.size.height / 2 -self.height);
    return photo;
}

/** 图片点击事件 */
- (void)photoTap: (UIGestureRecognizer *)photoTap {
    if (!self.isCancelTap) {
        return;
    }

    NSInteger index = self.bgScrollView.contentOffset.x / self.myFrame.size.width;
    JZLPhoto *photo = self.photos[index];
    UIScrollView *smScrollView =self.smallScViewArray[index];
    smScrollView.zoomScale = 1.0;
    //1.1如果是长图片先将其移动到CGPointMake(0, 0)在缩放回去
    if (CGRectGetHeight(photo.frame)>self.myFrame.size.height) {
        smScrollView.contentOffset = CGPointMake(0, 0);
    }
    [UIView animateWithDuration:0.3 animations:^{
        photo.transform = CGAffineTransformMakeScale(0.0001, 0.0001);
        //如果没传入原始的图片的frame,则不展示缩放动画
        self.blackView.alpha = 0;
        photo.alpha = 0;
        self.indexLbl.alpha = 0;
        self.saveBtn.alpha = 0;
    }completion:^(BOOL finished) {
        [self cancel];
        [self removeFromSuperview];
    }];

}

/** 图片放大缩小 */
- (void)zoomTap: (UIGestureRecognizer *)zoomTap {
    [UIView animateWithDuration:0.3 animations:^{
        UIScrollView *smallScrollView = (UIScrollView *)zoomTap.view.superview;
        if (smallScrollView.zoomScale > 1.0) {
            smallScrollView.zoomScale = 1.0;
        }else {
            smallScrollView.zoomScale = 3.0;
        }
    }];
}

#pragma mark UIScrollViewDelegate
//告诉scrollview要缩放的是哪个子控件
-(UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView{
    
    if (scrollView == self.bgScrollView) {
        return nil;
    }
    JZLPhoto *photo = self.photos[scrollView.tag];
    return photo;
}

- (void)scrollViewDidZoom:(UIScrollView *)scrollView{
    
    if ([scrollView isEqual:(UIScrollView *)self.bgScrollView]) return;
    JZLPhoto *photo = (JZLPhoto *)self.photos[scrollView.tag];
    CGFloat photoY = ((self.myFrame.size.height-self.height) - photo.frame.size.height)/2;
    CGRect photoF = photo.frame;
    if (photoY>0) {
        photoF.origin.y = photoY;
    }else{
        photoF.origin.y = 0;
    }
    photo.frame = photoF;
}

- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView {
    int index = scrollView.contentOffset.x / self.myFrame.size.width;
    
    if (self.bgScrollView == scrollView) {
        if (self.backPageNum) {
            self.backPageNum(index);
        }
    }
    if (self.index!= index ) {
        self.index = index;
        JZLPhoto *photo = self.photos[index];
        if(!photo.image){//滑动加载 不是一次性加载
            if (_loadImageType == kLoadImageTypeFromURL) {
                [self createImageScrollViewWithURL:[NSURL URLWithString:self.urlArr[index]] atIndex:index];
            }
        }
        for (UIView *view in scrollView.subviews) {
            if ([view isKindOfClass:[UIScrollView class]]) {
                UIScrollView *scrollView = (UIScrollView *)view;
                scrollView.zoomScale = 1.0;
            }
        }
    }
    self.indexLbl.text = [[NSString alloc] initWithFormat:@"%ld / %lu",(long)(self.index + 1) ,(unsigned long)self.photos.count];
}

- (void)savePhotos{
    UIView *view = [UIApplication sharedApplication].keyWindow;
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        NSString *dataStringUrl = @"";
        NSData *data = nil;
        if (self.loadImageType == kLoadImageTypeFromURL) {
            dataStringUrl = self.urlArr[self.index];
            data = [NSData dataWithContentsOfURL:[NSURL URLWithString:dataStringUrl]];
        }else{
            UIImage *image = self.imageArray[self.index];
            data = UIImagePNGRepresentation(image);
        }
        [[PHPhotoLibrary sharedPhotoLibrary] performChanges:^{
            [[PHAssetCreationRequest creationRequestForAsset] addResourceWithType:PHAssetResourceTypePhoto data:data options:nil];
        } completionHandler:^(BOOL success, NSError * _Nullable error) {
            dispatch_async(dispatch_get_main_queue(), ^{
                if(success && !error){
                    [view makeToast:@"保存成功"];
                }else
                    [view makeToast:@"保存失败"];
            });
        }];
    });
}

#pragma mark - lazy

- (UIButton *)saveBtn{
    if(!_saveBtn){
        _saveBtn = [[UIButton alloc] initWithFrame:CGRectMake(self.myFrame.size.width-60, self.myFrame.size.height-110, 40, 40)];
        [_saveBtn setImage:[UIImage imageNamed:@""] forState:UIControlStateNormal];
        [_saveBtn addTarget:self action:@selector(savePhotos) forControlEvents:UIControlEventTouchUpInside];
    }
    return _saveBtn;
}

- (UIView *)blackView {
    if (!_blackView) {
        _blackView = [[UIView alloc] initWithFrame:self.myFrame];
        _blackView.backgroundColor = [UIColor blackColor];
    }
    return _blackView;
}

- (UIScrollView *)bgScrollView {
    if (!_bgScrollView) {
        _bgScrollView = [[UIScrollView alloc] initWithFrame:self.myFrame];
        _bgScrollView.delegate = self;
        _bgScrollView.pagingEnabled = YES;
        _bgScrollView.bounces = YES;
        _bgScrollView.showsHorizontalScrollIndicator = NO;
        _bgScrollView.backgroundColor =  [UIColor clearColor];
        UITapGestureRecognizer *photoTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(photoTap:)];
        [_bgScrollView addGestureRecognizer:photoTap];
    }
    return _bgScrollView;
}

- (NSMutableArray *)photos {
    if (!_photos) {
        NSArray *array = @[];
        if (_loadImageType==kLoadImageTypeFromURL) {
            array = self.urlArr;
        }else if (_loadImageType == kLoadImageTypeFromImage){
            array = self.imageArray;
        }
        _photos = [[NSMutableArray alloc] initWithCapacity:array.count];
        [_photos removeAllObjects];
        for(NSUInteger index = 0 ; index<array.count ; index ++){
            [_photos addObject:[[JZLPhoto alloc] init]];
        }
    }
    return _photos;
}


- (NSArray *)urlArr {
    if (!_urlArr) {
        _urlArr = [NSArray array];
    }
    return _urlArr;
}

- (UILabel *)indexLbl {
    if (!_indexLbl) {
        _indexLbl = [[UILabel alloc] initWithFrame:CGRectMake((self.myFrame.size.width - 100) / 2, self.myFrame.size.height-100, 100, 30)];
        _indexLbl.backgroundColor = [UIColor colorWithWhite:0 alpha:0.3];
        _indexLbl.layer.masksToBounds = YES;
        _indexLbl.layer.cornerRadius = 4;
        _indexLbl.textColor = [UIColor whiteColor];
        _indexLbl.font = [UIFont systemFontOfSize:20];
        _indexLbl.textAlignment = NSTextAlignmentCenter;
        NSArray *array = @[];
        if (_loadImageType==kLoadImageTypeFromURL) {
            array = self.urlArr;
        }else if (_loadImageType == kLoadImageTypeFromImage){
            array = self.imageArray;
        }
        _indexLbl.text = [[NSString alloc] initWithFormat:@"%ld / %lu",(long)(self.index + 1) ,(unsigned long)array.count];
    }
    return _indexLbl;
}

- (NSMutableArray *)smallScViewArray {
    if (!_smallScViewArray) {
        _smallScViewArray = [NSMutableArray array];
    }
    return _smallScViewArray;
}
 
@end
